﻿Public Class PhoneNumberForm

    Sub New()

        ' 此调用是 Windows 窗体设计器所必需的。
        InitializeComponent()

        ' 在 InitializeComponent() 调用之后添加任何初始化。
        ctls(0) = Me.txtPhone1
        ctls(1) = Me.txtPhone2
        ctls(2) = Me.txtPhone3
        ctls(3) = Me.txtPhone4
        ctls(4) = Me.txtPhone5
        ' ctls(5) = Me.txtExtPhone

    End Sub

    '最大支持的电话号码数量
    Private TEL_NUM As Integer = 5

    '电话号码对应起始地址
    Private PhoneNum_offset As UShort = 2026

    '报警间隔时间起始地址
    Private AlarmInterval_offset As UShort = 2106

    '电话号码显示文本框数组
    Private ctls(TEL_NUM - 1) As TextBox


    '正在修改参数标志
    Private _isModify As Boolean = False


    Private Sub PhoneNumberForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        SetModifyState(False)
        Me.btnModify.Enabled = False
        Timer1.Start() ' LoadData()
#If LSC_PROJECTTYPE_SWITCH = "SALES" Then
        Me.btnSave.Visible = False
#End If
    End Sub

    ''' <summary>
    ''' 读取当前电话号码
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub LoadData()
        Dim buf() As Short
        If g_test Then
            ReDim buf(16 * TEL_NUM)
            Dim r As New Random
            For i As Integer = 0 To buf.Length - 1
                buf(i) = r.Next(1, 10)
            Next
        Else
            buf = COMHelper.Instance.Send4Short(g_netID, FunctionCode.WordWritableRead, PhoneNum_offset, 16 * TEL_NUM + 1)
        End If


        If buf Is Nothing Then
            Me.btnModify.Enabled = False
            msg.ShowError(g_strReadError)
            Exit Sub
        End If

        Me.btnModify.Enabled = True

        Dim bExtPhone As Boolean = False

        For i As Integer = 0 To TEL_NUM - 1
            Dim strPhone As String = ""

          

            For j As Integer = 0 To 15
                Dim t As Short
                t = buf(i * 16 + j)

                If t >= 0 AndAlso t <= 9 Then
                    strPhone += t.ToString()
                ElseIf t = Asc(",") Then
                    strPhone += ","
                ElseIf t = Asc("#") Then
                    strPhone += "#"
                Else
                    strPhone += " "
                End If

               
            Next


            If (strPhone.Contains(",")) Then
                ''========================
                '' 存在分机号码
                Dim strs() As String = strPhone.Split(",")
                txtExtPhone.Text = strs(0).Trim()
                txtExtPhone.Tag = strs(0).Trim()

                bExtPhone = True

                ctls(i).Text = strs(1).Trim()
                ctls(i).Tag = strs(1).Trim()
            Else
                ctls(i).Text = strPhone.Trim()
                ctls(i).Tag = strPhone.Trim()

                If buf(i * 16) <> 10 Then
                    txtExtPhone.Text = ""
                    txtExtPhone.Tag = ""
                End If
               
            End If
        Next

        ' Me.chkDirectDial.Checked = Not bExtPhone
        Me.chkDirectDial.Checked = bExtPhone
        Me.nudAlarmInterval.Value = buf(16 * TEL_NUM)
        Me.nudAlarmInterval.Tag = buf(16 * TEL_NUM)

    End Sub


    Private Sub btnClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClose.Click
        Me.TimerHeart.Stop()
        Me.Close()
    End Sub

    ''' <summary>
    ''' 开始修改
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub btnModify_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnModify.Click
        Me.btnModify.Enabled = False
        If EnterModify() = False Then
            'msg.Show("其它地方正在修改参数,请稍后再试.")
            Me.btnModify.Enabled = True
            Exit Sub
        End If

        SetModifyState(True)
    End Sub

    Private Sub SetModifyState(ByVal value As Boolean)
        Me.btnModify.Enabled = Not value
        Me.btnSave.Enabled = value

        Me.txtPhone1.ReadOnly = Not value
        Me.txtPhone2.ReadOnly = Not value
        Me.txtPhone3.ReadOnly = Not value
        Me.txtPhone4.ReadOnly = Not value
        Me.txtPhone5.ReadOnly = Not value

        Me.txtExtPhone.ReadOnly = Not value


        Me.chkDirectDial.Enabled = value

        If Me.chkDirectDial.Checked Then
            txtExtPhone.Enabled = True
        Else
            txtExtPhone.Enabled = False

        End If

        Me.nudAlarmInterval.Enabled = value

    End Sub

    ''' <summary>
    ''' 保存修改
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click
        If CheckValida() = False Then
            Exit Sub
        End If
        SetModifyState(False)

        Dim result As Boolean
        Me.Cursor = Cursors.WaitCursor
        _isSaving = True
        Me.btnModify.Enabled = False
        result = Save()
        _isSaving = False
        Me.Cursor = Cursors.Default
        If result Then
            SetModifyState(False)
            msg.Show("保存成功")
            LoadData()

        Else
            msg.ShowError("保存失败")
            Me.btnModify.Enabled = True
        End If
        '  SetModifyState(True)
    End Sub

    ''' <summary>
    ''' 判断用户输入数据的合法性
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function CheckValida() As Boolean
        If (Me.chkDirectDial.Checked) Then
            If Me.txtExtPhone.Text.Length = 0 Then
                msg.ShowWarning("需要填写分机拨号时先拨的号码。")
                Me.txtExtPhone.Focus()
                Return False
            End If

            Dim strTemp As String = txtExtPhone.Text.Replace("#", "")
            If (IsDigital(strTemp)) = False Then
                msg.ShowWarning("先拨的号码错误，只能是#或数字")
            End If
        Else


        End If

        If IsDigital(Me.txtPhone1.Text) = False Then
            msg.ShowWarning("电话号码只能是数字")
            Me.txtPhone1.Focus()
            Return False
        End If

        If IsDigital(Me.txtPhone2.Text) = False Then
            msg.ShowWarning("电话号码只能是数字")
            Me.txtPhone2.Focus()
            Return False
        End If

        If IsDigital(Me.txtPhone3.Text) = False Then
            msg.ShowWarning("电话号码只能是数字")
            Me.txtPhone3.Focus()
            Return False
        End If

        If IsDigital(Me.txtPhone4.Text) = False Then
            msg.ShowWarning("电话号码只能是数字")
            Me.txtPhone4.Focus()
            Return False
        End If

        If IsDigital(Me.txtPhone5.Text) = False Then
            msg.ShowWarning("电话号码只能是数字")
            Me.txtPhone5.Focus()
            Return False
        End If

        Dim val As Integer = 0
        For i As Integer = 0 To TEL_NUM - 1
            If Not String.IsNullOrEmpty(Trim(ctls(i).Text)) Then
                val += 2
            End If
        Next

        For i As Integer = 0 To TEL_NUM - 1

            If String.IsNullOrEmpty(Trim(ctls(i).Text)) Then
                Continue For
            End If

            For j As Integer = i + 1 To TEL_NUM - 1
                If String.IsNullOrEmpty(Trim(ctls(j).Text)) Then
                    Continue For
                End If

                If Trim(ctls(i).Text) = Trim(ctls(j).Text) Then
                    msg.ShowWarning("不能设置相同的报警号码")
                    Return False
                End If
            Next

        Next

        If nudAlarmInterval.Value < val OrElse nudAlarmInterval.Value > 30 Then
            'If nudAlarmInterval.Value > 30 Then
            msg.ShowWarning(String.Format("两次报警间隔的设置范围应该为{0}~10", val))
            Me.nudAlarmInterval.Focus()
            Return False
        End If

        Return True
    End Function

    ''' <summary>
    ''' 判断字符串是否为数字字符串
    ''' </summary>
    ''' <param name="str"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function IsDigital(ByVal str As String) As Boolean
        str = str.Trim()
        For i As Integer = 0 To str.Length - 1
            Dim c As Char
            c = str.Substring(i)
            'If c = "," OrElse c = "#" Then
            '    Continue For
            'End If
            If Not Char.IsDigit(c) Then
                Return False
            End If
        Next

        Return True
    End Function

    ''' <summary>
    ''' 保存所有电话号码
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function Save() As Boolean
        For i As Integer = 0 To ctls.Length - 1
            If ctls(i).Text.Trim() <> ctls(i).Tag.ToString().Trim() OrElse txtExtPhone.Text <> txtExtPhone.Tag Then  '
                Dim result As Boolean
                result = Save(ctls(i), i)
                If result = False Then
                    Return False
                End If
            End If
        Next

        If Me.nudAlarmInterval.Value <> Me.nudAlarmInterval.Tag Then
            Dim result As Boolean
            result = Save(AlarmInterval_offset, Me.nudAlarmInterval.Value)
            If result = False Then
                Return False
            End If
        End If


        '设置修改使能变量
        If ParameterModifyClass.SetModifyConfirm(g_netID) = False Then
            Return False
        End If

        ' Me.TimerHeart.Stop()

        '修改门变量
        If ExitModify() = False Then
            Debug.Write("ExitModify错误")
        End If

        Return True
    End Function

    ''' <summary>
    ''' 保存一个电话号码
    ''' </summary>
    ''' <param name="txt"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function Save(ByVal txt As TextBox, ByVal index As Integer) As Boolean
        Dim buf(15) As Byte
        Dim str As String = txt.Text.Trim()

        Dim strExtPhone As String = ""
        If (Me.chkDirectDial.Checked) Then

            strExtPhone = txtExtPhone.Text.Trim() + ","
        End If
        If Not (str.Trim().Length = 0) Then
            str = strExtPhone + str
        End If

        '将字符串电话号码转换成字节数组
        For i As Integer = 0 To Math.Min(15, str.Length - 1)
            Dim c As String
            c = str.Substring(i, 1)
            If c >= "0" AndAlso c <= "9" Then
                buf(i) = Integer.Parse(c)
            ElseIf c = "," OrElse c = "#" Then
                buf(i) = Asc(c)
            Else
                buf(i) = 10
            End If
        Next

        For j As Integer = str.Length To 15
            buf(j) = 10
        Next


        For j As Integer = 0 To buf.Length - 1
            Dim result As Boolean
            Dim offset As UShort = PhoneNum_offset + index * 16 + j
            result = Save(offset, buf(j)) ' COMHelper.Instance.Write(g_netID, FunctionCode.WordWrite, offset, buf(j))
            If result = False Then
                Return False
            End If
        Next

        Return True
    End Function


    ''' <summary>
    ''' 保存参数
    ''' </summary>
    ''' <param name="index"></param>
    ''' <param name="value"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function save(ByVal index As UShort, ByVal value As Short) As Boolean
        Dim offset As UShort = index + 1000
        Return COMHelper.Instance.Write(g_netID, FunctionCode.WordWrite, offset, value)
    End Function


    ''' <summary>
    ''' 进入修改
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function EnterModify() As Boolean
        If g_test Then
            _isModify = True
            Return True
        End If


        Dim result As Boolean
        result = ParameterModifyClass.EnterModify(g_netID)

        If result = False Then
            Return False
        End If

        '开始发送心跳包
        Me.TimerHeart.Start()

        _isModify = True

        Return True
    End Function


    ''' <summary>
    ''' 退出修改
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function ExitModify() As Boolean
        '门变量置为1
        Dim result As Boolean
        result = ParameterModifyClass.ExitModify(g_netID)

        '停止发送心跳包
        Me.TimerHeart.Stop()

        _isModify = False

        Return True
    End Function


#Region "发送心跳包"

    '心跳包连续发送错误的次数
    Private _heartFailCount As Integer = 0

    '心跳值
    Private _heartValue As Short = 0

    '心跳值是否初始化
    Private _bheartValue As Boolean = False

    '是否正在发送心跳标志
    Private _heartSending As Boolean = False

    '是否正在保存标志
    Public Shared _isSaving As Boolean = False

    '心跳包地址
    Private _heartIncreamentAddress As UShort = 7063

    ''' <summary>
    ''' 发送心跳包
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub HeartSend()
        If _bheartValue = False Then
            Dim b() As Short
            b = COMHelper.Instance.Send4Short(g_netID, FunctionCode.WordWritableRead, _heartIncreamentAddress, 1)
            If b IsNot Nothing AndAlso b.Length = 1 Then
                _heartValue = b(0)
                _bheartValue = True
            Else
                Exit Sub
            End If
        End If

        _heartValue = (_heartValue + 1) Mod UShort.MaxValue

        Dim result As Boolean
        result = COMHelper.Instance.Write(g_netID, FunctionCode.WordWrite, _heartIncreamentAddress, _heartValue)

        If result Then
            _heartFailCount = 0
        Else
            _heartFailCount += 1
        End If

        If _heartFailCount > 10 Then
            '提示用户可能断开连接了.
        End If

    End Sub

    ''' <summary>
    ''' 心跳定时器Tick事件
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub TimerHeart_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TimerHeart.Tick
        If Not g_HeartSend Then
            Exit Sub
        End If

        If _heartSending OrElse _isSaving Then
            Exit Sub
        End If

        _heartSending = True
        Me.HeartSend()
        _heartSending = False
    End Sub

#End Region

    Protected Overrides Sub OnClosing(ByVal e As System.ComponentModel.CancelEventArgs)
        Me.TimerHeart.Stop()
        MyBase.OnClosing(e)
    End Sub

    'Private Sub txtPhone1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles txtPhone1.KeyDown, txtPhone2.KeyDown, txtPhone3.KeyDown, txtPhone4.KeyDown, txtPhone5.KeyDown
    '    If e.KeyCode > Keys.D0 AndAlso e.KeyCode < Keys.D9 OrElse e.KeyCode = Keys.Back OrElse e.KeyCode = Keys.Delete OrElse e.KeyCode = Keys.Oemcomma Then
    '        'continue
    '    Else
    '        e.Handled = True
    '    End If
    'End Sub

    Private Sub txtPhone1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles txtPhone1.KeyPress, txtPhone2.KeyPress, txtPhone3.KeyPress, txtPhone4.KeyPress, txtPhone5.KeyPress, txtExtPhone.KeyPress
        If e.KeyChar.ToString() >= "0" AndAlso e.KeyChar.ToString() <= "9" OrElse e.KeyChar = "," OrElse e.KeyChar = "#" OrElse Asc(e.KeyChar) = 8 Then
            '有效字符
            e.Handled = False
        Else
            '无效字符
            e.Handled = True
        End If
    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        Timer1.Stop()
        LoadData()
    End Sub

    Private Sub nudAlarmInterval_GotFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles nudAlarmInterval.GotFocus
        'Dim val As Integer = 0
        'For i As Integer = 0 To TEL_NUM - 1
        '    If Not String.IsNullOrEmpty(Trim(ctls(i).Text)) Then
        '        val += 2
        '    End If
        'Next
        'nudAlarmInterval.Minimum = val
        'nudAlarmInterval.Maximum = 10
    End Sub

    Private Sub txtPhoneEx1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)

    End Sub

    Private Sub chkDirectDial_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkDirectDial.CheckedChanged
        If (chkDirectDial.Checked) Then
            txtExtPhone.Enabled = True

            ''txtExtPhone.Text = ""
        Else
            txtExtPhone.Enabled = False
            txtExtPhone.Text = ""


        End If
    End Sub
End Class